package com.zHan.controller;

import com.zHan.dto.RegisterDto;
import com.zHan.dto.UpdatePwdDto;
import com.zHan.exception.BaseException;
import com.zHan.pojo.Result;
import com.zHan.pojo.User;
import com.zHan.service.UserService;
import com.zHan.utils.JwtUtil;
import com.zHan.utils.Md5Util;
import com.zHan.utils.ThreadLocalUtil;
import jakarta.validation.Valid;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: UserController
 * Description:
 * date: 2023/11/7 0007 20:36
 *
 * @author zHan
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 用户注册
     *
     * @param dto
     * @return
     */
    @PostMapping("/register")
    public Result register(@Valid RegisterDto dto) {
        // 获取用户名
        String username = dto.getUsername();
        // 根据用户名查询用户
        User user = userService.findByUsername(username);
        // 用户名已存在
        if (user != null) {
            throw new BaseException("用户名已存在！");
        }
        // 注册
        return userService.register(dto);
    }

    /**
     * 用户登录
     *
     * @param dto
     * @return
     */
    @PostMapping("/login")
    public Result login(@Validated RegisterDto dto) {
        // 获取用户名
        String username = dto.getUsername();
        // 根据用户名查询用户
        User user = userService.findByUsername(username);
        // 用户名已存在
        if (user == null) {
            throw new BaseException("登录失败，用户名不存在");
        }
        // 检查密码是否正确
        String password = Md5Util.getMD5String(dto.getPassword());
        String dbPassword = user.getPassword();
        if (!password.equals(dbPassword)) {
            throw new BaseException("登录失败，密码错误");
        }
        // 存入id和username
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        String token = JwtUtil.genToken(claims);

        // 把token存储到redis中
        stringRedisTemplate.opsForValue().set(token, token, 1, TimeUnit.HOURS);

        // 返回jwt令牌
        return Result.success("登录成功", token);
    }

    /**
     * 获取用户详情
     *
     * @return
     */
    @GetMapping("/userInfo")
    public Result getUserInfo() {
        // 获取jwt令牌并解析
        Map<String, Object> claims = ThreadLocalUtil.get();
        String username = (String) claims.get("username");
        // 根据用户名查询用户
        User user = userService.findByUsername(username);
        if (user == null) {
            throw new BaseException("查询失败，数据不存在");
        }
        return Result.success(user);
    }

    /**
     * 更新用户信息
     *
     * @param user
     * @return
     */
    @PutMapping("/update")
    public Result update(@RequestBody @Validated User user) {
        return userService.update(user);
    }

    /**
     * 更新用户头像
     *
     * @param avatarUrl
     * @return
     */
    @PatchMapping("/updateAvatar")
    public Result updateAvatar(@RequestParam @URL String avatarUrl) {
        return userService.updateAvatar(avatarUrl);
    }

    /**
     * 更新用户密码
     *
     * @param dto
     * @return
     */
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody @Validated UpdatePwdDto dto,
                            @RequestHeader("Authorization") String token) {
        // 获取参数
        String old_pwd = dto.getOld_pwd();
        String new_pwd = dto.getNew_pwd();
        String re_pwd = dto.getRe_pwd();
        // 获取username
        Map<String, Object> claims = ThreadLocalUtil.get();
        String username = (String) claims.get("username");
        // 根据用户名查询密码
        String dbPassword = userService.findByUsername(username).getPassword();
        // 判断旧密码是否正确
        if (!Md5Util.getMD5String(old_pwd).equals(dbPassword)) {
            throw new BaseException("修改密码失败，旧密码不正确");
        }
        // 判断新密码和重复密码是否正确
        if (!new_pwd.equals(re_pwd)) {
            throw new BaseException("修改密码失败，两次填写的新密码不一样");
        }
        // 修改密码
        userService.updatePwd(new_pwd);
        // 删除redis中的token
        stringRedisTemplate.opsForValue().getOperations().delete(token);
        return Result.success("密码重置成功");
    }

}
